package my.dao.impl.rowmapper;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;

import my.dao.DaoException;
import my.dao.NullUniqueResultRowMapper;



public class AutoBeanRowMapperImpl<BeanType> implements NullUniqueResultRowMapper<BeanType> {	
	
	private Class<BeanType> beanClass;
	
	public AutoBeanRowMapperImpl(Class<BeanType> beanClass){
		this.beanClass=beanClass;
	}
	
	private  void putRsFdToBeanFd(Object bean,Method setMd,ResultSet rs,String fdName) throws IllegalAccessException, IllegalArgumentException, InvocationTargetException, SQLException,DaoException{
		
		Class<?> paramType=setMd.getParameterTypes()[0];
		
		if(paramType==String.class||paramType==String.class){
			setMd.invoke(bean, rs.getString(fdName));
		}else if(paramType==int.class||paramType==Integer.class){
			setMd.invoke(bean, rs.getInt(fdName));
		}else if(paramType==double.class||paramType==Double.class){
			setMd.invoke(bean, rs.getDouble(fdName));
		}else if(paramType==float.class||paramType==Float.class){
			setMd.invoke(bean, rs.getFloat(fdName));
		}else if(paramType==long.class||paramType==Long.class){
			setMd.invoke(bean, rs.getLong(fdName));
		}else if(paramType==boolean.class||paramType==Boolean.class){
			setMd.invoke(bean, rs.getBoolean(fdName));
		}else if(paramType==java.util.Date.class){
			setMd.invoke(bean, rs.getTimestamp(fdName));
		}else if(paramType==java.sql.Date.class){
			setMd.invoke(bean, rs.getDate(fdName));
		}else if(paramType==java.sql.Timestamp.class){
			setMd.invoke(bean, rs.getTimestamp(fdName));
		}else if(paramType==java.sql.Time.class){
			setMd.invoke(bean, rs.getTime(fdName));
		}else if(paramType==short.class||paramType==Short.class){
			setMd.invoke(bean, rs.getShort(fdName));
		}else if(paramType==short.class||paramType==Short.class){
			setMd.invoke(bean, rs.getShort(fdName));
		}else if(paramType==byte.class||paramType==Byte.class){
			setMd.invoke(bean, rs.getShort(fdName));
		}else{
			throw new DaoException("目前Dao尚不支持的bean属性的类型："+paramType.getName());
		}		
	}

	public BeanType currRow2Obj(ResultSet rs) throws SQLException,
			DaoException {
		
		try {
			
			BeanType bean= beanClass.newInstance();
			
			ResultSetMetaData rsmd=rs.getMetaData();
			
			Method[] mds=beanClass.getMethods();
			
			for(Method md:mds){
				
				String mdName=md.getName();
				
				if(mdName.startsWith("set")&&mdName.length()>3&&md.getParameterTypes().length==1){
					
					String fdName=mdName.substring(3,4).toLowerCase()+mdName.substring(4);
					
					//判断该字段名称在结果集中是否存在
					boolean existsFdName=false;
					for(int i=1;i<=rsmd.getColumnCount();i++){						
						if(fdName.equalsIgnoreCase(rsmd.getColumnLabel(i))){
							existsFdName=true;
							break;
						}
					}
					
					if(existsFdName){						
						this.putRsFdToBeanFd(bean, md, rs, fdName);
					}
					
					
				}
			}
			return bean;
		} catch (Exception e) {
			if(e instanceof DaoException){
				throw (DaoException)e;
			}
			throw new DaoException(e);
		}
		
	}

}
